<h2>Why is this an issue?</h2>
<p>Public fields in public classes do not respect the encapsulation principle and have three main disadvantages:</p>
<ul>
  <li> Additional behavior such as validation cannot be added. </li>
  <li> The internal representation is exposed, and cannot be changed afterwards. </li>
  <li> Member values are subject to change from anywhere in the code and may not meet the programmer’s assumptions. </li>
</ul>
<p>To prevent unauthorized modifications, private attributes and accessor methods (set and get) should be used.</p>
<p>Note that due to optimizations on simple properties, public fields provide only very little performance gain.</p>
<h3>What is the potential impact?</h3>
<p>Public fields can be modified by any part of the code and this can lead to unexpected changes and hard-to-trace bugs.</p>
<p>Public fields don’t hide the implementation details. As a consequence, it is no longer possible to change how the data is stored internally without
impacting the client code of the class.</p>
<p>The code is harder to maintain.</p>
<h3>Exceptions</h3>
<p>Fields marked as <code>readonly</code> or <code>const</code> are ignored by this rule.</p>
<p>Fields inside classes or structs annotated with <code>[StructLayout]</code> are ignored by this rule.</p>
<p>Fields inside classes or structs annotated with <code>[Serializable]</code> are ignored by this rule unless they are annotated with
<code>[NonSerialized]</code>.</p>
<h2>How to fix it</h2>
<p>Depending on your needs:</p>
<ul>
  <li> Use auto-implemented properties:<br> For common cases, where no validation is required, auto-implemented properties are a good alternative to
  fields: these allows fine grained access control and offers the flexibility to add validation or change internal storage afterwards. <em>Note:</em>
  as a bonus it is now possible to monitor value changes using breakpoints. </li>
  <li> Encapsulate the fields in your class. To do so:
    <ol>
      <li> Make the field private. </li>
      <li> Use public properties (set and get) to access and modify the field. </li>
    </ol>  </li>
  <li> Mark field as <code>readonly</code> or <code>const</code>. </li>
</ul>
<h3>Code examples</h3>
<h4>Noncompliant code example</h4>
<pre data-diff-id="1" data-diff-type="noncompliant">
public class Foo
{
    public int InstanceData = 32; // Noncompliant
    public int AnotherInstanceData = 32; // Noncompliant

}
</pre>
<h4>Compliant solution</h4>
<pre data-diff-id="1" data-diff-type="compliant">
public class Foo
{
    // using auto-implemented properties
    public int InstanceData { get; set; } = 32;

    // using field encapsulation
    private int _anotherInstanceData = 32;

    public int AnotherInstanceData
    {
        get { return _anotherInstanceData; }
        set
        {
            // perform validation
            _anotherInstanceData = value;
        }
    }

}
</pre>
<h3>Pitfalls</h3>
<p>Please be aware that changing a field by a property in a software that uses serialization could lead to binary incompatibility.</p>
<h2>Resources</h2>
<ul>
  <li> CWE - <a href="https://cwe.mitre.org/data/definitions/493">CWE-493 - Critical Public Variable Without Final Modifier</a> </li>
</ul>

